import json
import logging
import os
import traceback
import uuid

from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View
from django.views.decorators.clickjacking import xframe_options_deny, xframe_options_sameorigin

from ImgSplicing import settings
from apps.img.Utils.SplicingUtils import splicing
from apps.img.Utils.ThreadPool import global_thread_pool
from apps.img.models import imgInfo, SplicingInfo, SplicingImgInfo

logger = logging.getLogger('django')


class index(View):

    def get(self, request):
        print(request.user.is_authenticated)
        if request.user.is_authenticated:
            return render(request, 'index.html')
        else:
            return redirect(reverse('user:login'))

    def post(self, request):
        backData = {'state': '0', 'message': '访问index'}
        return HttpResponse(json.dumps(backData, ensure_ascii=False), content_type="application/json,charset=utf-8")


def get_deep_data(path='media/buffer/'):
    result = []
    buffer_path = os.path.join(settings.BASE_DIR, path)
    data = os.listdir(buffer_path)
    for i in data:
        if os.path.isdir(i):
            get_deep_data(i)
        else:
            result.append(i)
    return result


class CheckChunk(View):
    def post(self, request):
        # 获得上传文件块的大小,如果为0，就告诉他不要上传了
        chunkSize = request.POST.get("chunkSize")
        if chunkSize == '0':
            return JsonResponse({'ifExist': True})
        # 如果文件块大小不为0 ，那么就上传，需要拼接一个临时文件
        file_name = request.POST.get('fileMd5') + request.POST.get('chunk')

        # 如果说这个文件不在已经上传的目录，就可以上传，已经存在了就不需要上传。
        if file_name not in get_deep_data():
            return JsonResponse({'ifExist': False})
        return JsonResponse({'ifExist': True})


class Upload(View):
    def post(self, request):
        md5 = request.POST.get("fileMd5")
        chunk_id = request.POST.get("chunk", "0")
        fileName = "%s-%s" % (md5, chunk_id)
        file = request.FILES.get('file')
        file_path = os.path.join(settings.BASE_DIR, "media/")
        with open(file_path + fileName, 'wb') as f:
            for i in file.chunks():
                f.write(i)
        return JsonResponse({'upload_part': True})


class mergeChunks(View):
    def post(self, request):
        user = request.user
        fileName = request.POST.get("fileName")
        md5 = request.POST.get("fileMd5")
        id = request.POST.get("fileId")
        chunk = 0
        file_uuid = str(uuid.uuid1())

        fileType = fileName[fileName.rfind('.'):]
        imgName = file_uuid + fileType
        path = os.path.join('media/', imgName)
        with open(path, 'wb') as fp:
            while True:
                try:
                    fileName = 'media/' + '/{}-{}'.format(md5, chunk)
                    with open(fileName, 'rb') as f:
                        fp.write(f.read())
                    os.remove(fileName)
                except:
                    break
                chunk += 1
        img = imgInfo()
        img.id = file_uuid
        img.file_name = imgName
        img.file_path = path
        img.upload_by = user
        img.img_type = fileType
        img.save()
        return JsonResponse({'upload': True, 'fileName': fileName, 'fileId': id})


def batch_thread(splicing_id):
    try:
        splicing(splicing_id)
        logger.info('异步任务执行完成:\n %s' % splicing_id)
    except Exception:
        trace_log = traceback.format_exc()
        logger.error('异步任务执行失败:\n %s' % trace_log)


class SplicingImg(View):
    def get(self, request):
        return render(request, 'splicing.html')

    def post(self, request):
        req = json.loads(request.body)
        user = request.user
        col_total = req['total_col']
        row_total = req['total_row']
        imgs = req['data_list']
        ctx = {}
        try:
            splicingInfo = SplicingInfo()
            splicing_uuid = str(uuid.uuid1())
            splicingInfo.id = splicing_uuid
            splicingInfo.splicing_col = int(col_total)
            splicingInfo.splicing_row = int(row_total)
            splicingInfo.main_img_col = 1
            splicingInfo.main_img_row = 1
            splicingInfo.progress = 0
            splicingInfo.save()
            for img in imgs:
                row = img['row']
                col = img['col']
                id = img['img_id']
                img_Info = SplicingImgInfo()
                info = imgInfo.objects.get(id=id)
                img_Info.id = str(uuid.uuid1())
                img_Info.img_col = col
                img_Info.img_row = row
                img_Info.splicing_info = splicingInfo
                img_Info.img_info = info
                img_Info.save()
            future = global_thread_pool.executor.submit(batch_thread(splicingInfo.id), splicingInfo.id)
            global_thread_pool.future_dict[splicingInfo.id] = future
            ctx["state"] = "0"
            ctx["message"] = "提交成功"
            response = HttpResponse(json.dumps(ctx, ensure_ascii=False), content_type="application/json,charset=utf-8")
            return response
        except BaseException:
            ctx["state"] = "1"
            ctx["message"] = "提交失败"
            response = HttpResponse(json.dumps(ctx, ensure_ascii=False), content_type="application/json,charset=utf-8")
            return response


class ImgListView(View):
    @xframe_options_sameorigin
    def get(self, request):
        user = request.user
        imgid = request.GET.get('imgid')
        img_list = imgInfo.objects.get_default_img(user=user)
        ctx = {"img_list": img_list, "img_id": imgid}
        return render(request, 'imgList.html', ctx)

    def post(self, request):
        user = request.user
        img_list = imgInfo.objects.get_default_img(user=user)
        ctx = {}
        if img_list is not None:
            ctx["state"] = "0"
            ctx["message"] = "查询成功"
            ctx["data_list"] = []
            for img in img_list:
                img_data = {"id": img.id, "name": img.file_name, "path": img.file_path}
                ctx["data_list"].append(img_data)
        else:
            ctx["state"] = "1"
            ctx["message"] = "数据为空"
            ctx["data_list"] = []
        response = HttpResponse(json.dumps(ctx, ensure_ascii=False), content_type="application/json,charset=utf-8")
        return response
